package com.minivision.fdiot.util;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;

/**
 * 图片处理工具类
 * @author hughzhao
 * @2018年3月1日
 */
public class ImageUtils {

  public static BufferedImage getBufferedImage(byte[] img) throws IOException {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(img);
    return ImageIO.read(inputStream);
  }

  public static byte[] writeImageToBytes(BufferedImage image, String format) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    ImageWriter writer = ImageIO.getImageWritersByFormatName(format).next();
    writer.setOutput(ImageIO.createImageOutputStream(output));
    writer.write(image);
    return output.toByteArray();
  }

  public static BufferedImage resize(BufferedImage img, int newW, int newH) {
    int w = img.getWidth();
    int h = img.getHeight();
    BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
    Graphics2D g = dimg.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
    g.dispose();
    return dimg;
  }

  private static final int MAX_LENGTH = 800;

  public static BufferedImage resize(BufferedImage image) {
    int width = image.getWidth();
    int height = image.getHeight();
    BufferedImage image_new;
    if (width > MAX_LENGTH && height < MAX_LENGTH) {
      image_new = resize(image, MAX_LENGTH, (int) height * MAX_LENGTH / width);
    } else if (width < MAX_LENGTH && height > MAX_LENGTH) {
      image_new = resize(image, (int) width * MAX_LENGTH / height, MAX_LENGTH);
    } else if (width > MAX_LENGTH && height > MAX_LENGTH) {
      if (width > height) {
        image_new = resize(image, MAX_LENGTH, (int) height * MAX_LENGTH / width);
      } else {
        image_new = resize(image, (int) width * MAX_LENGTH / height, MAX_LENGTH);
      }
    } else {
      image_new = image;
    }
    return image_new;
  }

  public static BufferedImage rotateImage(BufferedImage bufferedimage, int degree) {
    int w = bufferedimage.getWidth();
    int h = bufferedimage.getHeight();
    Dimension destRec = calcRotatedSize(new Dimension(w, h), degree);
    int type = bufferedimage.getColorModel().getTransparency();
    BufferedImage img = new BufferedImage(destRec.width, destRec.height, type);
    Graphics2D graphics2d = img.createGraphics();
    graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2d.translate((destRec.width - w) / 2, (destRec.height - h) / 2);
    graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);
    graphics2d.drawImage(bufferedimage, 0, 0, null);
    graphics2d.dispose();
    return img;
  }

  private static Dimension calcRotatedSize(Dimension src, int angel) {
    if (Math.abs(angel) >= 90) {
      if (angel / 90 % 2 == 1) {
        int temp = src.height;
        src.height = src.width;
        src.width = temp;
      }
      angel %= 90;
    }
    double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2.0D;
    double len = 2.0D * Math.sin(Math.toRadians(angel) / 2.0D) * r;
    double angel_alpha = (3.141592653589793D - Math.toRadians(angel)) / 2.0D;
    double angel_dalta_width = Math.atan(src.height / src.width);
    double angel_dalta_height = Math.atan(src.width / src.height);

    int len_dalta_width =
        (int) (len * Math.cos(3.141592653589793D - angel_alpha - angel_dalta_width));
    int len_dalta_height =
        (int) (len * Math.cos(3.141592653589793D - angel_alpha - angel_dalta_height));
    int des_width = src.width + len_dalta_width * 2;
    int des_height = src.height + len_dalta_height * 2;
    return new Dimension(des_width, des_height);
  }
  
}
